package org.example.foodhealth.controller;

import org.example.foodhealth.bean.UserLogin;
import org.example.foodhealth.config.JwtTokenUtils;
import org.example.foodhealth.config.VerificationCode;
import org.example.foodhealth.dto.Response;
import org.example.foodhealth.dto.UserLoginDTO;
import org.example.foodhealth.service.UserLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mail.MailSendException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/UserLogin")
public class UserLoginController {
    @Autowired
    private VerificationCode verificationCode;

    @Autowired
    private UserLoginService userLoginService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 发送验证码
    @PostMapping("/send-verification-code")
    public ResponseEntity<String> sendVerificationCode(@RequestBody Map<String, String> requestBody) { // 使用 @RequestBody
        String email = requestBody.get("email"); // 从 JSON 请求体中获取 email
        try {
            // 验证电子邮件格式
            if (!isValidEmail(email)) {
                return ResponseEntity.badRequest().body("无效的电子邮件地址。");
            }

            // 发送验证码
            verificationCode.sendVerificationCode(email);
            return ResponseEntity.ok("验证码已发送至 " + email);
        } catch (MailSendException e) {
            // 邮件发送异常处理
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("邮件发送失败：请检查您的邮件设置。");
        } catch (Exception e) {
            // 处理其他异常
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("错误类型：" + e.getClass().getSimpleName() + "，错误信息：" + e.getMessage());
        }
    }

    // 简单的电子邮件格式验证方法
    private boolean isValidEmail(String email) {
        return email != null && email.matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$");
    }

    // 验证验证码
    @PostMapping("/verify-code")
    public ResponseEntity<String> verifyCode(@RequestBody Map<String, String> requestBody) {
        String email = requestBody.get("email");
        String code = requestBody.get("code");

        // 验证验证码
        boolean isValid = verificationCode.verifyCode(email, code);
        if (!isValid) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid verification code");
        }

        // 保存验证状态（例如，存入 Redis）
        verificationCode.saveValidCode(email);

        return ResponseEntity.ok("Verification code is valid");
    }

    // 注册用户
    @PostMapping("/register")
    public ResponseEntity<String> register(@RequestBody UserLoginDTO userLoginDTO) {
        String email = userLoginDTO.getEmail();
        String password = userLoginDTO.getPassword();
        String phone = userLoginDTO.getPhone();

        // 检查验证码验证状态
        boolean isCodeValid = verificationCode.checkValidCode(email);
        if (!isCodeValid) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Please verify your code first");
        }

        // 注册用户
        userLoginService.registerUser(userLoginDTO);

        // 取消验证码的有效状态（可选）
        verificationCode.invalidateCode(email);

        return ResponseEntity.ok("User registered successfully");
    }

    //登录
    @PostMapping("/login")
    public Response<Map<String, Object>> loginUser(@RequestBody Map<String, String> loginRequest) {
        String phone = loginRequest.get("phone");
        String password = loginRequest.get("password");

        // 校验手机号是否为空
        if (phone == null || phone.isEmpty()) {
            return Response.newFail("手机号不能为空");
        }

        // 查找用户
        Optional<UserLogin> userOptional = userLoginService.getUserByPhone(phone);
        if (userOptional.isEmpty()) {
            return Response.newFail("手机号未注册");
        }

        UserLogin user = userOptional.get();
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

        // 校验密码
        if (!passwordEncoder.matches(password, user.getPassword())) {
            return Response.newFail("密码错误");
        }

        // 生成 JWT Token
        String token = JwtTokenUtils.generateToken(user);

        // 将 Token 存入 Redis，有效期 24 小时
        redisTemplate.opsForValue().set("user_" + user.getId(), token, 24, TimeUnit.HOURS);

        // 返回用户信息和 Token
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("Id", user.getId());
        result.put("Phone", user.getPhone());
        result.put("Email", user.getEmail());

        return Response.newSuccess(result);
    }

    //修改密码
    @PostMapping("/reset-password")
    public ResponseEntity<String> resetPassword(@RequestBody Map<String, String> requestBody) {
        String email = requestBody.get("email");
        String code = requestBody.get("code");
        String newPassword = requestBody.get("newPassword");
        String confirmPassword = requestBody.get("confirmPassword");

        // 1. 验证邮箱格式
        if (!isValidEmail(email)) {
            return ResponseEntity.badRequest().body("无效的电子邮件地址");
        }

        // 2. 验证验证码
        boolean isCodeValid = verificationCode.verifyCode(email, code);
        if (!isCodeValid) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("验证码错误或已过期");
        }

        // 3. 检查新密码和确认密码是否一致
        if (!newPassword.equals(confirmPassword)) {
            return ResponseEntity.badRequest().body("新密码和确认密码不一致");
        }

        // 4. 查找用户
        Optional<UserLogin> userOptional = userLoginService.getUserByEmail(email);
        if (userOptional.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("该邮箱未注册");
        }

        UserLogin user = userOptional.get();

        // 5. 加密新密码并更新
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encryptedPassword = passwordEncoder.encode(newPassword);
        user.setPassword(encryptedPassword);
        userLoginService.updateUser(user); // 这里需要在 service 层实现更新密码的方法

        // 6. 使验证码失效（可选）
        verificationCode.invalidateCode(email);

        return ResponseEntity.ok("密码修改成功");
    }
}
